package com.monkey.luffer.springboot.demo.basis.kcc.test;


import net.lingala.zip4j.core.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.model.FileHeader;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class StringCombinationsRecursive {
        private static final String CHARACTERS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
        private static final String CHARACTERS1 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        private static final String CHARACTERS2 = "abcdefghijklmnopqrstuvwxyz";
        private static final String CHARACTERS3 = "0123456789";
        private static final String CHARACTERS4 = "0123456789abcdefghijklmnopqrstuvwxyz";
        private static final String CHARACTERS5 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        private static final String CHARACTERS6 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
        private static final int MIN_LENGTH = 4;
        private static final int MAX_LENGTH = 6;
        private static long count = 0;
        private static final String dest = "/Users/jiahong.liu/Downloads/《架构师修炼之道》/22";

        public static void main(String[] args) throws Exception {
            String source = "/Users/jiahong.liu/Downloads/《架构师修炼之道》/架构师修炼之道_.zip";
            File zipFile = new File(source);
            // 首先创建ZipFile指向磁盘上的.zip文件
            ZipFile zFile = new ZipFile(zipFile);
            zFile.setFileNameCharset("UTF-8");

            // 解压目录
            File destDir = new File(dest);
            if (!destDir.exists()) {
                // 目标目录不存在时，创建该文件夹
                destDir.mkdirs();
            }
            String [] chart = new String[] {CHARACTERS, CHARACTERS1, CHARACTERS2,CHARACTERS3,CHARACTERS4,CHARACTERS5,CHARACTERS6};
            for(int i = 0; i < chart.length; i++ ) {
                String ele = chart[i];
                new Thread(() -> {
                    for (int length = MIN_LENGTH; length <= MAX_LENGTH; length++) {
                        int loop = length;
                        new Thread(() -> {
                            System.out.println("开始" + ele + "第" + loop + "位 " + System.currentTimeMillis());
                            try {
                                generateCombinationsRecursive("", loop, ele, zFile, destDir);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                            System.out.println("结束" + ele + "第" + loop + "位 " + System.currentTimeMillis());
                        }).start();

                    }
                }).start();
            }
        }

        private static void generateCombinationsRecursive(String current, int remaining, String characters,  ZipFile zFile, File destDir) throws Exception {
            if (remaining == 0) {
                count++;
                boolean flag = false;
                try {
                    unZip(zFile,
                            destDir, current);
                    flag = true;
                }catch (Exception e) {
                    // ignore
                } finally {
                    if (flag) {
                        System.out.println("正常密码为：" + current);
                        throw new RuntimeException("success");
                    }
                }

                return;
            }

            for (int i = 0; i < characters.length(); i++) {
                generateCombinationsRecursive(current + characters.charAt(i), remaining - 1, characters, zFile, destDir);
            }
        }


    /**
     * @param password 解压文件密码(可以为空)
     */
    public static void unZip(ZipFile zFile , File destDir, String password) throws ZipException {
        if (zFile.isEncrypted()) {
            // 设置密码
            zFile.setPassword(password.toCharArray());
        }
        // 将文件抽出到解压目录(解压)
        zFile.extractAll(dest);
        List<FileHeader> headerList = zFile.getFileHeaders();
        List<File> extractedFileList = new ArrayList<File>();
        for (FileHeader fileHeader : headerList) {
            if (!fileHeader.isDirectory()) {
                extractedFileList.add(new File(destDir, fileHeader.getFileName()));
            }
        }

        File[] extractedFiles = new File[extractedFileList.size()];

        extractedFileList.toArray(extractedFiles);

        for (File f : extractedFileList) {
            System.out.println(f.getAbsolutePath() + "文件解压成功!");
        }
    }

}

